package domain.user ;

import java.util.Set ;

import persistence.Persistent ;
import presentation.UIMember ;

/**
 * a registered member to the forum. members have username and password.
 *
 * @author idan
 */
public class Member extends User implements UIMember
{
	private static final long serialVersionUID = -7826907342004045555L ;

	/** indicates if the user is currently logged-in **/
	private transient boolean active ;

	/** the user's ENCRYPTED password */
	private String encryptedPassword ;

	/** the username **/
	private String username ;

	/** the user's first name **/
	private String firstName;

	/** the user's last name **/
	private String lastName;

	/** the user's date of birth**/
	private String dateOfBirth;

	/** the user's gender - "Male" or "Female"  **/
	private String gender;

	/** the user's place of residence **/
	private String residence;



	/**
	 * @param id id of this member.
	 * @param username user name.
	 * @param encryptedPassword encrypted password of this member.
	 * @param privileges privileges of this user.
	 * @post this.getPrivileges() = privileges
	 * @post this.getName() = name && this.getPassword() = password
	 * @post this.isActive() = false
	 */
	public Member(final long id, final String username, final String encryptedPassword,
		final Set<Privilege> privileges)
	{
		this(id, username, encryptedPassword, privileges, "", "", "", "", "") ;
	}

	/**
	 * @param id id of this member.
	 * @param username user name.
	 * @param encryptedPassword encrypted password of this member.
	 * @param privileges privileges of this user.
	 * @param firstName first name of the user.
	 * @param lastName last name of the user.
	 * @param dateOfBirth date of birth.
	 * @param gender male/female.
	 * @param residence where the user lives (free text).
	 * @post this.getPrivileges() = privileges
	 * @post this.getName() = name && this.getPassword() = password
	 * @post this.isActive() = false
	 */
	public Member (final long id, final String username, final String encryptedPassword,
		final Set<Privilege> privileges, final String firstName, final String lastName,
		final String dateOfBirth, final String gender, final String residence)
	{
		super(id,privileges);
		this.username = username ;
		this.encryptedPassword = encryptedPassword ;
		this.active = false ;
		this.firstName = firstName;
		this.lastName = lastName;
		this.dateOfBirth = dateOfBirth;
		this.gender = gender;
		this.residence = residence;
	}

	// for serialization
	@SuppressWarnings("unused")
	private Member()
	{
		super(Persistent.INVALID_ID, null) ;
		this.active = false ;
		this.username = null ;
		this.encryptedPassword = null ;
	}

	/**
	 * @see presentation.UIMember#getDateOfBirth()
	 */
	public String getDateOfBirth()
	{
		return this.dateOfBirth;
	}

	/**
	 * @see presentation.UIMember#getFirstName()
	 */
	public String getFirstName()
	{
		return this.firstName ;
	}

	/**
	 * @see presentation.UIMember#getGender()
	 */
	public String getGender()
	{
		return this.gender ;
	}

	/**
	 * @see presentation.UIMember#getLastName()
	 */
	public String getLastName()
	{
		return this.lastName ;
	}

	/**
	 * @return password of the user.
	 */
	public String getPassword()
	{
		return this.encryptedPassword ;
	}

	/**
	 * @see presentation.UIMember#getResidence()
	 */
	public String getResidence()
	{
		return this.residence ;
	}

	/**
	 * @see presentation.UIMember#getUsername()
	 */
	public String getUsername()
	{
		this.lockRead() ;
		try
		{
			return this.username ;
		}
		finally
		{
			this.unlockRead() ;
		}
	}

	/**
	 * @return whether this user is currently in session.
	 */
	public boolean isActive()
	{
		this.lockRead() ;
		try
		{
			return this.active ;
		}
		finally
		{
			this.unlockRead() ;
		}
	}

	/**
	 * set this member to be active or non-active
	 * @param isActive indicates if the user is active now
	 */
	public void setActive(final boolean isActive)
	{
		this.lockWrite() ;
		try
		{
			this.active = isActive ;
		}
		finally
		{
			this.unlockWrite() ;
		}
	}

	/**
	 * @param dateOfBirth the dateOfBirth to set
	 */
	public void setDateOfBirth(final String dateOfBirth)
	{
		this.lockWrite() ;
		try
		{
			this.dateOfBirth= dateOfBirth;
		}
		finally
		{
			this.unlockWrite() ;
		}
	}

	/**
	 * @param firstName the firstName to set
	 */
	public void setFirstName(final String firstName)
	{
		this.lockWrite() ;
		try
		{
			this.firstName = firstName ;
		}
		finally
		{
			this.unlockWrite() ;
		}
	}

	/**
	 * @param gender the gender to set
	 */
	public void setGender(final String gender)
	{
		this.lockWrite() ;
		try
		{
			this.gender = gender ;
		}
		finally
		{
			this.unlockWrite() ;
		}
	}

	/**
	 * @param lastName the lastName to set
	 */
	public void setLastName(final String lastName)
	{
		this.lockWrite() ;
		try
		{
			this.lastName= lastName ;
		}
		finally
		{
			this.unlockWrite() ;
		}
	}

	/**
	 * @param residence the residence to set
	 */
	public void setResidence(final String residence)
	{
		this.lockWrite() ;
		try
		{
			this.residence = residence ;
		}
		finally
		{
			this.unlockWrite() ;
		}
	}

	/**
	 * @param name new name for this member.
	 * @post this.getName() = 'name'.
	 */
	public void setUsername(final String name)
	{
		this.lockWrite() ;
		try
		{
			this.username = name ;
		}
		finally
		{
			this.unlockWrite() ;
		}
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString()
	{
		return super.toString() + " " + this.getUsername() ;
	}

	/**
	 * @return the encrypted password.
	 */
	protected String getEncryptedPassword()
	{
		this.lockRead() ;
		try
		{
			return this.encryptedPassword ;
		}
		finally
		{
			this.unlockRead() ;
		}
	}

	/**
	 * @param encryptedPassword password to set, in its encrypted form.
	 */
	protected void setEncryptedPassword(final String encryptedPassword)
	{
		this.lockWrite() ;
		try
		{
			this.encryptedPassword = encryptedPassword ;
		}
		finally
		{
			this.unlockWrite() ;
		}
	}



}
